package server

import (
	"common/database/config"
	"context"
	"errors"
	"golang.org/x/crypto/bcrypt"
	"math/rand"
	"time"
	"user_srv/internal/models/dao"
	"user_srv/internal/models/service"
	pb "user_srv/proto"
)

type Server struct {
	pb.UnimplementedUserServer
}

func (c *Server) Register(ctx context.Context, request *pb.RegisterRequest) (*pb.RegisterResponse, error) {
	password, err := bcrypt.GenerateFromPassword([]byte(request.Password), bcrypt.DefaultCost)
	if err != nil {
		return nil, errors.New("注册失败")
	}
	user := dao.User{
		Tel:      request.Tel,
		Password: string(password),
		Username: request.Tel,
	}
	err = config.DB.Create(&user).Error
	if err != nil {
		return nil, errors.New("注册失败")
	}
	return &pb.RegisterResponse{Id: int64(user.ID)}, nil
}

func (c *Server) Login(ctx context.Context, request *pb.LoginRequest) (*pb.LoginResponse, error) {
	key := "login_user" + request.Tel
	log := "login_user_loc" + request.Tel
	cmd := config.Rdb.Get(config.Ctx, log)
	if cmd.Val() >= "3" {
		return nil, errors.New("短时间内密码多次输入错误，请稍后再试")
	}
	message := service.UserSendMessage(request.Tel, request.SendCode)
	if message != "" {
		return nil, errors.New(message)
	}
	//查询用户信息
	var user *dao.User
	err := config.DB.Where("tel=?", request.Tel).Find(&user).Limit(1).Error
	if err != nil {
		return nil, errors.New("登录失败")
	}
	if user.ID == 0 {
		return nil, errors.New("登录失败,用户不存在")
	}
	err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(request.Password))
	if err != nil {
		config.Rdb.Incr(config.Ctx, log)
		config.Rdb.Expire(config.Ctx, log, time.Minute*1)
		return nil, errors.New("登录失败，密码错误")
	}
	config.Rdb.Del(config.Ctx, key)
	config.Rdb.Del(config.Ctx, log)
	return &pb.LoginResponse{Id: int64(user.ID)}, nil
}

func (c *Server) SendMessage(ctx context.Context, request *pb.SendMessageRequest) (*pb.SendMessageResponse, error) {
	key := "login_user" + request.Tel
	//生成随机4位数验证码
	i := rand.Intn(9000) + 1000
	//调用阿里云短信发送
	/*err := pkg.SendMessage(strconv.Itoa(i), request.Tel)
	if err != nil {
		return nil, errors.New("短信发送失败请稍后再试")
	}*/
	//将短信验证码存入缓存设置3分钟过期时间
	config.Rdb.Set(config.Ctx, key, i, time.Minute*3)
	return &pb.SendMessageResponse{}, nil
}
